package com.ymk;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.ymk.base.cmd.ACmd;
import com.ymk.base.cmd.CmdSign;
import com.ymk.base.exception.MallException;
import com.ymk.base.utlis.Aes;
import com.ymk.base.utlis.ParamsBuilder;
import com.ymk.bo.rbac.RbacPermBO;
import com.ymk.bo.rbac.RbacRoleBO;
import com.ymk.bo.user.SopUserBO;
import com.ymk.core.code.cmd.RbacCmdCode;
import com.ymk.core.code.cmd.SessionCmdCode;
import com.ymk.core.code.cmd.UserCmdCode;
import com.ymk.core.constants.SysConstants;
import com.ymk.core.enums.sop.SopUserStatusEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class SopSessionPostCmd extends ACmd {

    @Override
    public CmdSign executeSop(HttpServletRequest request, CmdSign sign) throws Exception {
        CmdSign respSign = new CmdSign(sign);
        SopUserBO reqData = super.getData(sign, SopUserBO.class);

        ParamsBuilder paramsBuilder = ParamsBuilder.newBuild()
                .addParam("mobile", reqData.getMobile())
                .addParam("loadRole",true);

        CmdSign sopGetCmd = CmdSign.Builder.newBuild(sign)
                .setCmdCode(UserCmdCode.SOP_USER_GET)
                .setSource(paramsBuilder.build())
                .setScope(SysConstants.CMD_SERVER_SCOPE)
                .build();
        CmdSign sopGetSign = this.scheduler.schedule(request, sopGetCmd);
        SopUserBO dbSopUserBO = super.getData(sopGetSign, SopUserBO.class);

        if (Objects.isNull(dbSopUserBO)) {
            throw new MallException("用户不存在");
        }

        if (dbSopUserBO.getStatus().equals(SopUserStatusEnum.DISABLED.getStatus())) {
            throw new MallException("账号已禁用");
        }

        if (!Aes.getMD5(reqData.getPassword(), dbSopUserBO.getSalt()).equals(dbSopUserBO.getPassword())) {
            throw new MallException("密码错误");
        }

        paramsBuilder.clearParam()
                .addParam("id",dbSopUserBO.getRbacUserRoleBO().getRoleId())
                .addParam("loadPerm",true);

        CmdSign roleGetCmd = CmdSign.Builder.newBuild(sign)
                .setCmdCode(RbacCmdCode.RBAC_ROLE_GET)
                .setSource(paramsBuilder.build())
                .setScope(SysConstants.CMD_SERVER_SCOPE)
                .build();
        CmdSign permGetCmd = this.scheduler.schedule(request, roleGetCmd);
        RbacRoleBO rbacRoleBO = super.getData(permGetCmd, RbacRoleBO.class);
        List<RbacPermBO> rbacPermBOList = rbacRoleBO.getRbacPermBOList().stream()
                .sorted(Comparator.comparing(RbacPermBO::getSort).reversed())
                .collect(Collectors.toList());
        rbacRoleBO.setRbacPermBOList(rbacPermBOList);
        dbSopUserBO.setRbacRoleBO(rbacRoleBO);

        String token = IdUtil.simpleUUID();
        dbSopUserBO.setPassword("");
        dbSopUserBO.setSalt("");
        dbSopUserBO.setToken(token);
        this.redisTemplate.opsForValue().set(SysConstants.REDIS_KEY_JWT + token, JSON.toJSONString(dbSopUserBO), 60 * 60 * 4);

        respSign.setSource(super.getSource(dbSopUserBO));
        return respSign;
    }

    @Override
    public CmdSign verify(HttpServletRequest request, CmdSign sign) throws Exception {
        SopUserBO sopUserBO = super.getData(sign, SopUserBO.class);
        if (StringUtils.isBlank(sopUserBO.getMobile())) {
            throw new MallException("手机号为空");
        }
        if (StringUtils.isBlank(sopUserBO.getPassword())) {
            throw new MallException("密码为空");
        }
        return null;
    }

    @Override
    public boolean anon(CmdSign sign) {
        return true;
    }

    @Override
    public String getCmdCode() {
        return SessionCmdCode.SOP_MEMBER_POST;
    }

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
}
